package org.java.search.service.impl;

import com.alibaba.fastjson.JSON;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.java.common.util.JsonUtils;
import org.java.common.vo.ResultVo;
import org.java.item.entity.Sku;
import org.java.search.service.SearchService;
import org.java.search.util.MapToObject;
import org.java.search.util.MapToSku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author WHQ
 * @version 1.0
 * @date 2022-3-8 0008 下午 4:10
 */
@Service
public class SearchServiceImpl implements SearchService {
    //注入es执行对象
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Value("${es.index}")
    private String index;
    @Override
    public ResultVo<Sku> search(String title,Integer page,Integer limit) throws Exception {
        System.out.println(title);
        //开始从es中搜索
        //1.得到搜索的请求对象
        SearchRequest searchRequest = new SearchRequest(index);
        //2.构建搜索构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3.指定匹配的条件
        MatchQueryBuilder matchQueryBuilder= QueryBuilders.matchQuery("title",title);
//        TermQueryBuilder termQueryBuilder=QueryBuilders.termQuery("id",3234250);
        //4.将搜索条件放入到搜索的构建器中
        sourceBuilder.query(matchQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //高亮设置
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //设置不需要多个关键字高亮
        highlightBuilder.requireFieldMatch(false);
        //设置需要高亮的字段
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        sourceBuilder.from((page-1)*limit);
        sourceBuilder.size(limit);
        sourceBuilder.highlighter(highlightBuilder);
        //5.将搜索条件添加到搜索请求中
        searchRequest.source(sourceBuilder);
        //6.执行搜索,得到响应实体
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //6.从响应实体中得到hits
        SearchHit[] hits = searchResponse.getHits().getHits();
        //获得总条数
        TotalHits totalHits = searchResponse.getHits().getTotalHits();
        //获得总条数
        long count = totalHits.value;
        System.out.println("总条数:"+count);
        List<Sku> list=new ArrayList<>();
        for (SearchHit hit : hits) {
            System.out.println("进来了");
            //解析高亮的字段
            //1.首先获得高亮的字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            //原来的结果
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
            //得到需要高亮的字段
            HighlightField highFields = highlightFields.get("title");
            if (highFields!=null){
                Text[] fragments = highFields.fragments();
                String newTitle="";
                for (Text text : fragments) {
//                    System.out.println("text"+text);
                    newTitle+=text;
                }
                //置换原来的title
                sourceAsMap.put("title",newTitle);
            }
//            Sku sku = MapToObject.map2Object(sourceAsMap, Sku.class);
//            System.out.println(sku);
            Sku sku = MapToSku.mapToSku(sourceAsMap);
//            Sku parse = JsonUtils.parse(JsonUtils.serialize(sourceAsMap), Sku.class);
            System.out.println(sku.getTitle());
            list.add(sku);
        }
        ResultVo<Sku> vo=new ResultVo<>();
        vo.setData(list);
        vo.setPageNum(page);
        vo.setCount(count);
        int maxPage= (int) (count%limit==0?count/limit:(count/limit)+1);
//        System.out.println(maxPage);
        vo.setMaxPage(maxPage);
        return vo;
    }
}
